import json

from pyecharts_javascripthon.api import TRANSLATOR

from flask import Flask, render_template
from flask_socketio import SocketIO, send, emit

from src.Tools.AdbTools import AdbTools
from src.event.EventBus import EventManager, Event
from src.monitor.MonitorCenter import MonitorCenter
from src.ui.SystemChart import SystemChart

app = Flask(__name__)
socketio = SocketIO(app, async_mode='threading')

REMOTE_HOST = "https://pyecharts.github.io/assets/js"


@app.route("/")
def hello():
    global monitor_center

    df_info = monitor_center.retrieve_data()
    chart = SystemChart(df_info)

    view = chart.update()
    return render_template(
        "pyecharts.html",
        title='7012 Monitor',
        # myechart=view.render_embed(),
        host=REMOTE_HOST,
        script_list=view.get_js_dependencies(),
    )


######################
@socketio.on('message')
def handle_message(message):
    print('received message: ' + message)
    send(message)


@socketio.on('json')
def handle_json(json):
    print('received json: ' + str(json))
    send(json, json=True)


@socketio.on('my event', namespace='/chat')
def handle_my_custom_event(json):
    print('[chat] received json: ' + str(json))
    emit('my response', json)


@socketio.on('connect', namespace='/chat')
def handle_chat_connect():
    print('[chat] Client connected.')
    EventManager.add_event_listener(Event.ON_STATE_CHANGED, handle_thread_state_changed)


@socketio.on('disconnect', namespace='/chat')
def handle_chat_disconnect():
    print('[chat] Client disconnected')
    EventManager.remove_event_listener(Event.ON_STATE_CHANGED, handle_thread_state_changed)


@socketio.on('info', namespace='/chat')
def handle_event(json):
    print('[info] received json: ' + str(json))
    EventManager.emit(Event(Event.ON_CHART_UPDATE))
    emit('woow', 'cha cha', namespace='/news')


@socketio.on('command', namespace='/chat')
def handle_command(arg):
    global monitor_center

    print('[command] ' + str(arg))

    if arg['cmd'] == 'monitorState':
        emit('monitorState', monitor_center.state(), namespace='/chat')
    elif arg['cmd'] == 'getConnectedIpAddress':
        emit('getConnectedIpAddress', monitor_center.get_connected_ip_address(), namespace='/chat')
    elif arg['cmd'] == 'startMonitor':
        monitor_center.start(arg['DeviceIp'])
    elif arg['cmd'] == 'stopMonitor':
        monitor_center.stop()
    elif arg['cmd'] == 'normalizeData':
        monitor_center.set_normalize(arg['data'])
    elif arg['cmd'] == 'getNormalizeData':
        emit('getNormalizeData', monitor_center.get_normalize(), namespace='/chat')
    elif arg['cmd'] == 'getAdbDevices':
        emit('getAdbDevices', AdbTools.get_devices(), namespace='/chat')
    elif arg['cmd'] == 'adbConnect':
        AdbTools.connect(arg['DeviceIp'])
        emit('getAdbDevices', AdbTools.get_devices(), namespace='/chat')
    elif arg['cmd'] == 'adbDisconnect':
        AdbTools.dis_connect(arg['DeviceIp'])
        emit('getAdbDevices', AdbTools.get_devices(), namespace='/chat')


def handle_thread_state_changed(arg: Event):
    socketio.emit('monitorState', arg.dict['state'], namespace='/chat')
    if arg.dict['state'] == 'Running':
        EventManager.add_event_listener(Event.ON_CHART_UPDATE, handle_chart_update)
    else:
        EventManager.remove_event_listener(Event.ON_CHART_UPDATE, handle_chart_update)


def handle_chart_update(arg: Event):
    global monitor_center
    df_info = monitor_center.retrieve_data()
    chart = SystemChart(df_info)
    view = chart.update()
    options = view.get_options()
    snippet = TRANSLATOR.translate(options).as_snippet()
    json_dic = json.loads(snippet)
    js_data = json.dumps(json_dic)
    socketio.emit('chart_update', "var op = " + snippet, namespace='/chat')


######################

monitor_center = None


def main():
    global monitor_center

    event_mgr = EventManager()
    monitor_center = MonitorCenter()

    event_mgr.start()
    socketio.run(app, host='0.0.0.0', port=1234)
    event_mgr.stop()


if __name__ == '__main__':
    main()
